feat(frontend): make quote freshness and currency validation explicit in send flow - #296
Open
woahwhattheheck wants to merge 16 commits into
Open
woahwhattheheck wants to merge 16 commits into
woahwhattheheck wants to merge 16 commits into
Conversation
Show quote source, timestamps, expiry, and currency metadata on the card. Invalidate pending quotes on field or network changes, refuse to confirm expired or mismatched prices, and bind the quote id into the transfer payload so displayed and serialized amounts stay reconciled. Closes RemitFlow#279
Avoid applying the input locale again after parsing the amount. Keep connected-wallet balance comparisons exact for integer, fractional and canonical string balances, with real App regressions and production before/after screenshots.
Use the repository Prettier configuration for the newly added test block. The normalized Babel AST is identical; production code and observed behavior are unchanged.
Stop when connection returns no account, and compare the bound quote against the returned wallet balance before addTransfer. Cover rejected, insufficient, affordable and exact-balance connections through the actual App and local demonstration service, with production browser before/after screenshots.
…ction A wallet connection can finish after a network drop has cleared the reviewed quote. Keep a confirmation version across renders and refuse the stale continuation before transfer creation, including when connectivity recovers before the wallet resolves. Field invalidation and quote refresh also retire the earlier confirmation. An explicit new review remains available after the existing submission lock is released. Two mounted-App regressions reproduce unwanted createTransfer calls on parent 14c8de4 and pass with this change. They use deferred wallet connection with the real local transfer service and storage, assert zero writes for the invalidated attempt, then exactly one transfer bound to a fresh quote after explicit review. Validation: 75/75 across format, quote-binding, quote-contract, and send-money-quote-freshness suites (Node 24.19.0 / Vitest 4.1.10); production Vite build passed. Package and lock files unchanged. This is a focused continuation; the full suite and hosted CI were not rerun. Earlier documented full-suite failures remain outside this change. Existing contribution and PR retained.
…ecks A valid amount that cannot be priced now receives a pricing failure message instead of an incorrect amount-validation error. The existing precision fixture traverses review, confirmation and the result dialog before checking submission and receipts. Negative values remain negative in the localized text input and cannot create a transfer. Preserve exact exponent amounts, serialized fees/rates/receipts, quote-to-receipt equality, contract rejection diagnostics and the existing unquotable/no-create assertion. No production path other than the null-quote message changes. Focused validation on Node 24.19.0 / Vitest 4.1.10: all 7 cases in test/integration/send-money-precision.test.jsx passed in 8.31s; no skips. Used the retained matching package/lock/runtime, repository Vite config with only cacheDir relocated in an isolated source copy, one worker and disabled test cache. Full suite/build/browser/provider execution was not repeated. Reproduce: node node_modules/vitest/vitest.mjs run test/integration/send-money-precision.test.jsx --maxWorkers=1 --fileParallelism=false Executed source blob: 08679cc Executed test blob: 136b66c Parent: 6fe01b6 Refs RemitFlow#279
The two existing failing offline/reconnect cases requested review but expected dispatch or navigation immediately. Exercise the actual confirmation and success dialogs before checking a recovered transfer, and explicitly confirm before injecting the existing mid-flight connection failure. Preserve offline button/handler blocking, the recovery notice, no automatic resubmission, exact once-only creation and the honest unknown-status message. Assert no transfer before explicit confirmation. Pin only the unrelated demonstration wallet's random refusal so the connectivity checks remain deterministic. Product source is unchanged. One maintained-file execution: all 6 cases in test/integration/offline-reconnect.test.jsx passed, zero skips, 4.75s on Node 24.19.0 / Vitest 4.1.10. Used an isolated source copy, retained matching dependencies, the existing Vite config with only cacheDir redirected, one worker and disabled test cache. Full suite/build/provider execution remains separate. Reproduce: node node_modules/vitest/vitest.mjs run test/integration/offline-reconnect.test.jsx --maxWorkers=1 --fileParallelism=false Executed test blob: 363db74 Unchanged SendMoney blob: 08679cc Parent: 84510d0 Refs RemitFlow#279
Both form and dialog controls display Sending during wallet connection. Scope the disabled-button assertion to the confirmation dialog so it selects the intended control and the test can await completion instead of abandoning pending wallet work. Pin only the demonstration wallet's random rejection. Preserve validation feedback, no transfer before connection, exactly one transfer after rapid confirm clicks or synchronous submit events, safe-failure retry, and a valid submission after invalid input. Product source is unchanged. One affected maintained-file execution: test/integration/send-money-form.test.jsx passed all 7 cases, zero skips, in 11.52s on Node 24.19.0 / Vitest 4.1.10. Executed in an isolated source copy with the existing Vite config; only cacheDir was relocated. One worker, no test cache. Full-suite validation remains a separate combined check. Reproduce: node node_modules/vitest/vitest.mjs run test/integration/send-money-form.test.jsx --maxWorkers=1 --fileParallelism=false --cache=false Executed test blob: a642327 Unchanged SendMoney blob: 08679cc Parent: eb89ddb Refs RemitFlow#279
Quote parsing removes redundant decimal zeros. Preserve exact string and value assertions while expecting canonical 100.1, 0.6, and 99.5 amounts. Retain the original 0.30 USD floating-point regression. The current minimum fee is 0.25, leaving 0.05 USD; the 17.1 MXN rate gives 0.855, which must round half-up to 0.86. Assert the minimum fee explicitly and retain the below-fee zero clamp using a 0.20 USD quote. No product behavior or parser validation changes, and neither original test is removed or skipped. Affected maintained file test/unit/quote.test.js: 2 passed, 0 failed, 0 skipped in 1.28s on Node 24.19.0 / Vitest 4.1.10. Executed in an isolated source copy with the existing Vite config, relocating only cacheDir. One worker, no test cache. Combined full-suite validation is separate. Reproduce: node node_modules/vitest/vitest.mjs run test/unit/quote.test.js --maxWorkers=1 --fileParallelism=false --cache=false Executed test blob: 9461138 Parent: 9f4f56f Refs RemitFlow#279
The existing CI runs npm run format:check before tests and build. Its equivalent Prettier check reproduced 15 flagged files on the complete 348-blob tracked source at 4f74e1f. Apply only the existing formatter's output to those exact files; 333 other tracked blobs remain unchanged. No formatter configuration, ignore rules, dependencies, package scripts, or functional changes. Validation and cache artifacts were kept outside the tracked source copy. Reused installed Prettier 3.9.6 and the repository's existing configuration; no install was performed. Actual check: node /dev/shm/meridian-da83-rf296-runtime/node_modules/prettier/bin/prettier.cjs --check . Before: exit 1, 15 files flagged. Repair: the same CLI with --write and only the 15 flagged paths. After: exit 0, All matched files use Prettier code style. No tests rerun for formatting; the single combined package suite and build follow on this composed source. Formatted paths: - src/components/QuoteCard.jsx - src/context/AppContext.jsx - src/hooks/useTransfers.js - src/pages/SendMoney.jsx - src/services/errors.js - src/services/quote.js - src/utils/quoteBinding.js - test/components/WalletButton.test.jsx - test/integration/offline-reconnect.test.jsx - test/integration/send-money-form.test.jsx - test/integration/send-money-quote-freshness.test.jsx - test/unit/AppContext.wallet.test.jsx - test/unit/quote-binding.test.js - test/unit/useTransfers.errors.test.jsx - vite-plugin-security-headers.js Parent: 4f74e1f Refs RemitFlow#279
Record the complete test selection at 17dd96c: 485 passed, zero failed or skipped, across all 49 files. Preserve the 348-file source manifest, unchanged raw Vitest output, formatter evidence, critical-threshold audit and production build receipts. Record hosted CI and Lighthouse action_required separately from local results, and retain all noncritical audit findings. This commit adds three evidence files and leaves every tested source blob unchanged. Attribution: GPT-6 Astra Pro / Astra Relay-17 / ChatGPT cloud harness 15a9c3b91fc7.
Preserve all recorded commands, source and runtime identities, validation results, limitations, and raw evidence. Application source and archived execution data are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #279
Summary
Bind each transfer to the quote the sender reviewed, and refuse confirmation when the quote, wallet connection, connectivity, or available balance cannot support it. This includes the original quote-freshness work and the subsequent locale, balance, and pending-connection corrections.
Changes
Compatibility and tradeoffs
Quote id/source and Transfer quoteId are additive; legacy records still parse. Identical priced inputs and clock produce the same quote ID; a later refresh produces a new one. Before dispatch, a network interruption clears the pending quote and requires a new review. Already-dispatched transfers retain their existing result handling.
Current validation
Tested source: 17dd96c4. The evidence-only child 91347ff3 and subsequent report update 5b36c889 preserve all tested source files.
Validation boundary
Execution uses the repository's demonstration wallet and transfer service in jsdom. No live wallet/provider/settlement integration or application-performance improvement is established by these results. Dependency files are unchanged; the audit findings above remain. Raw output retains existing React/Vite warnings.
Earlier Chromium and local Lighthouse evidence remains tied to its original tested source and was not rerun in this continuation. The existing Vite development CSP/React-preamble issue is separate.
At the tested source, hosted CI and Lighthouse CI report action_required. Local formatting, tests, critical-audit, and build checks pass; hosted acceptance remains separate.